﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml.Linq;

namespace NetSurveillance.WebApp.Utilities
{
    public class XmlResource
    {
        public static IDictionary<string, IDictionary<string, string>> XmlResources;

        public static IDictionary<string, IDictionary<string, string>> ItactCodes; 

        public static void LoadXmlResourceData(string filePath, string fileName)
        {
            if(XmlResources == null)
                XmlResources = new Dictionary<string, IDictionary<string, string>>();
            var fileDic = new DirectoryInfo(filePath);
            var allXmlFiles = fileDic.GetFiles(fileName + "*.xml");
            foreach (FileInfo xmlResourceFile in allXmlFiles)
            {
                string resourceFileName = Path.GetFileNameWithoutExtension(xmlResourceFile.Name);
                string langStr = PresetValues.DefaultLang;
                if (!string.IsNullOrWhiteSpace(resourceFileName) && resourceFileName.Contains("."))
                {
                    langStr = resourceFileName.Substring(resourceFileName.IndexOf('.'));
                }
                LoadXmlFile(langStr, xmlResourceFile.FullName);
            }
        }

        public static void LoadItactCodeEles(string fullPath)
        {
            if (ItactCodes == null)
                ItactCodes = new Dictionary<string, IDictionary<string, string>>();
            if (!File.Exists(fullPath))
                return;
            var itactCodesEle = XElement.Load(fullPath);
            if (itactCodesEle.IsEmpty) return;
            foreach (var codesEle in itactCodesEle.Elements("Codes"))
            {
                var langAttr = codesEle.Attribute("lang");
                string lang = (langAttr == null || string.IsNullOrWhiteSpace(langAttr.Value))
                                  ? PresetValues.DefaultLang
                                  : langAttr.Value;
                LoadItactCodes(lang, codesEle);
            }
        }

        /// <summary>
        /// 根据ActionCode格式化字符串
        /// </summary>
        /// <param name="code">ActionCode</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public static string Format(string code, params string[] values)
        {
            string formatStr = GetResourceValue(code);
            if (string.IsNullOrWhiteSpace(code) || string.IsNullOrWhiteSpace(formatStr)) return null;
            int maxParam = GetMaxParam(formatStr) + 1;
            if (maxParam > values.Length)
            {
                values = values.Concat(new string[maxParam - values.Length]).ToArray();
            }
            return string.Format(formatStr, values);
        }

        private static int GetMaxParam(string formatStr)
        {
            if (string.IsNullOrWhiteSpace(formatStr)) return -1;
            var reg = new Regex(@"\{(?<param>\d)\}");
            var matchs = reg.Matches(formatStr);
            if (matchs.Count == 0) return -1;
            int maxParam = -1;
            foreach (Match match in matchs)
            {
                int param;
                if (match.Success && int.TryParse(match.Groups["param"].Value, out param) &&
                    param > maxParam)
                    maxParam = param;
            }
            return maxParam;
        }

        public static string GetResourceValue(string code)
        {
            string currentLang = Thread.CurrentThread.CurrentUICulture.Name.ToLower();
            if (!XmlResources.ContainsKey(currentLang))
            {
                currentLang = PresetValues.DefaultLang.ToLower();
                if (!XmlResources.ContainsKey(currentLang))
                    XmlResources[currentLang] = new Dictionary<string, string>();
            }
            var xmlResourceDic = XmlResources[currentLang];
            return xmlResourceDic == null || !xmlResourceDic.ContainsKey(code) ? null : xmlResourceDic[code];
        }

        public static string GetItactCodeValue(string code)
        {
            string currentLang = Thread.CurrentThread.CurrentUICulture.Name.ToLower();
            if (!ItactCodes.ContainsKey(currentLang))
            {
                currentLang = PresetValues.DefaultLang.ToLower();
                if (!ItactCodes.ContainsKey(currentLang))
                    ItactCodes[currentLang] = new Dictionary<string, string>();
            }
            var itactCodeDic = ItactCodes[currentLang];
            return itactCodeDic == null || string.IsNullOrWhiteSpace(code) || !itactCodeDic.ContainsKey(code)
                       ? null
                       : itactCodeDic[code];
        }

        private static void LoadXmlFile(string lang, string fullPath)
        {
            lang = lang.ToLower();
            if(!XmlResources.ContainsKey(lang))
                XmlResources[lang] = new Dictionary<string, string>();
            var resourceElement = XElement.Load(fullPath);
            if(resourceElement.IsEmpty) return;
            foreach (XElement dataEle in resourceElement.Elements("Data"))
            {
                var codeAttr = dataEle.Attribute("code");
                var valueAttr = dataEle.Attribute("value");
                if(codeAttr == null || valueAttr == null || string.IsNullOrWhiteSpace(codeAttr.Value)) continue;
                XmlResources[lang][codeAttr.Value] = valueAttr.Value;
            }
        }

        private static void LoadItactCodes(string lang, XElement codesEle)
        {
            lang = lang.ToLower();
            if (!ItactCodes.ContainsKey(lang))
                ItactCodes[lang] = new Dictionary<string, string>();
            if (codesEle == null || codesEle.IsEmpty) return;
            foreach (var dataEle in codesEle.Elements("Data"))
            {
                var codeAttr = dataEle.Attribute("code");
                var valueAttr = dataEle.Attribute("value");
                if (codeAttr == null || valueAttr == null || string.IsNullOrWhiteSpace(codeAttr.Value)) continue;
                ItactCodes[lang][codeAttr.Value] = valueAttr.Value;
            }
        }
    }
}